import { defineComponent } from 'vue';

const AppRatingProps = {
  /**
   * 双向绑定值
   * @type {String}
   * @memberof AppRatingProps
   */
  value: {
    type: String,
  },

  /**
   * 表单项名称
   * @type {String}
   * @memberof AppRatingProps
   */
  name: String,

  /**
   * 图标大小
   * @type {String}
   * @memberof AppRatingProps
   */
  size: {
    type: Number,
    default: 20,
  },

  /**
   * 是否禁用
   * @type {boolean}
   * @memberof AppRatingProps
   */
  disabled: Boolean,

  /**
   * 只读模式
   * @type {boolean}
   * @memberof AppSlider
   */
  readonly: Boolean,

  /**
   * 最大值
   * @type {string}
   * @memberof AppSlider
   */
  maxValue: {
    type: Number,
    default: 5,
  },

  /**
   * 最小值
   * @type {string}
   * @memberof AppSlider
   */
  minValue: {
    type: Number,
    default: 0,
  },

  /**
   * 步进值
   * @type {string}
   * @memberof AppSlider
   */
  stepValue: Number,

  /**
   * 浮点精度
   * @type {string}
   * @memberof AppSlider
   */
  precision: Number,
};

export const AppRating = defineComponent({
  name: 'AppRating',
  props: AppRatingProps,
  emits: ['editorValueChange'],
  data() {
    const starList: any[] = [];
    return {
      starList: starList,
    };
  },
  methods: {
    /**
     * 值改变事件
     *
     * @param {*} e
     */
    valueChange(value: number, e: MouseEvent) {
      if (Object.is(this.stepValue, 0.5) && 2 * e.offsetX < this.size) {
        this.$emit(
          'editorValueChange',
          value < this.minValue ? this.formatValue(this.minValue) : this.formatValue(value - 0.5),
        );
      } else {
        this.$emit(
          'editorValueChange',
          value < this.minValue ? this.formatValue(this.minValue) : this.formatValue(value),
        );
      }
    },

    formatValue(value: number) {
      if (this.precision) {
        return value.toFixed(this.precision);
      } else {
        return value.toString();
      }
    },
  },
  mounted() {
    for (let i = 1; i <= this.maxValue; i++) {
      this.starList.push({
        cssName: 'star',
        isSelect: false,
        isHalf: false,
        value: i,
      });
    }
  },
  updated() {
    this.starList.forEach((star: any, index: number) => {
      star.isSelect = index < Number(this.value) ? true : false;
      star.isHalf = index + 0.5 === Number(this.value) ? true : false;
    });
  },
  render() {
    return (
      <div class={{ 'app-rating': true, 'app-rating--disabled': this.disabled, 'app-rating--readonly': this.readonly }}>
        {this.starList.map(star => {
          return (
            <div
              class={{ 'rating-item': true, 'rating-item--active': star.isSelect, 'rating-item--half': star.isHalf }}
              style={{ fontSize: this.size / 50 + 'rem' }}
            >
              <app-icon
                onClick={(e: MouseEvent) => {
                  this.valueChange(star.value, e);
                }}
                name={star.cssName}
              />
              {star.isHalf ? (
                <app-icon
                  onClick={(e: MouseEvent) => {
                    this.valueChange(star.value, e);
                  }}
                  name='star-half-outline'
                />
              ) : null}
            </div>
          );
        })}
      </div>
    );
  },
});
